﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Data.Entity.ModelConfiguration.Configuration;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Reflection;
using System.Text;
using DomainDriver.CommonUtilities.Reflectors;

namespace DomainDriver.DomainModeling.StorageManagers.EntityFrameworkStorage
{
    public class ForceMappedConvention : Convention
    {
        public ForceMappedConvention()
        {
            Types().Having(GetForceMappedProperties).Configure((config, properties) => MapProperties(config, properties));
        }

        private IEnumerable<PropertyInfo> GetForceMappedProperties(Type entityType)
        {
            var desiredBindings = (BindingFlags.SetProperty | BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Instance);
            var forceMappedProperties = entityType.GetProperties(desiredBindings).Where(propInfo => ClassReflector.HasAttributeDeclaration<ForceMappedAttribute>(propInfo)).ToList();
            return (forceMappedProperties.Count > 0) ? forceMappedProperties : null;
        }

        private static void MapProperties(ConventionTypeConfiguration config, IEnumerable<PropertyInfo> properties)
        {
            foreach (PropertyInfo prop in properties)
            {
                if (!ClassReflector.HasAttributeDeclaration<ForceMappedAttribute>(prop))
                { continue; }

                config.Property(prop);
            }
        }
    }
}